/**
 * Copyright (c) The openTCS Authors.
 *
 * This program is free software and subject to the MIT license. (For details,
 * see the licensing information (LICENSE.txt) you should have received with
 * this copy of the software.)
 */
package org.opentcs.guing.components.properties.panel;

import com.google.inject.Inject;
import java.awt.Dimension;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
import javax.swing.JPanel;
import javax.swing.table.AbstractTableModel;
import org.opentcs.data.model.Location;
import org.opentcs.data.model.Path;
import org.opentcs.data.model.Point;
import org.opentcs.data.model.TCSResourceReference;
import org.opentcs.guing.components.dialogs.DetailsDialogContent;
import org.opentcs.guing.components.properties.type.ResourceProperty;
import org.opentcs.guing.components.properties.type.Property;
import org.opentcs.guing.util.I18nPlantOverview;
import org.opentcs.thirdparty.jhotdraw.util.ResourceBundleUtil;
import org.opentcs.util.gui.StringTableCellRenderer;

/**
 * UI for viewing a resource property without being able to edit the property.
 *
 * @author Leonard Schüngel (Fraunhofer IML)
 */
public class ResourcePropertyViewerEditorPanel
    extends JPanel
    implements DetailsDialogContent {

  /**
   * A resource bundle.
   */
  private static final ResourceBundleUtil BUNDLE
      = ResourceBundleUtil.getBundle(I18nPlantOverview.PROPERTIES_PATH);
  /**
   * The property edited.
   */
  private ResourceProperty fProperty;

  /**
   * Creates a new instance.
   */
  @Inject
  public ResourcePropertyViewerEditorPanel() {
    initComponents();

    itemsTable.setModel(new ItemsTableModel());
    itemsTable.setDefaultRenderer(
        TCSResourceReference.class,
        new StringTableCellRenderer<TCSResourceReference<?>>(ref -> ref == null ? "" : ref.getName())
    );

    setPreferredSize(new Dimension(400, 200));
  }

  @Override
  public void setProperty(Property property) {
    fProperty = (ResourceProperty) property;

    ItemsTableModel model = (ItemsTableModel) itemsTable.getModel();

    List<List<TCSResourceReference<?>>> values = new ArrayList<>();
    for (Set<TCSResourceReference<?>> set : fProperty.getItems()) {
      List<TCSResourceReference<?>> entry = Arrays.asList(null, null, null);
      set.forEach(resource -> {
        if (resource.getReferentClass() == Path.class) {
          entry.set(0, resource);
        }
        else if (resource.getReferentClass() == Point.class) {
          entry.set(1, resource);
        }
        else if (resource.getReferentClass() == Location.class) {
          entry.set(2, resource);
        }
      });
      values.add(entry);
    }
    model.setValues(values);

  }

  @Override
  public void updateValues() {
  }

  @Override
  public String getTitle() {
    return BUNDLE.getString("resourcePropertyViewerEditorPanel.title");
  }

  @Override
  public ResourceProperty getProperty() {
    return fProperty;
  }

  /**
   * This method is called from within the constructor to initialize the form.
   * WARNING: Do NOT modify this code. The content of this method is always
   * regenerated by the Form Editor.
   */
  // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
  private void initComponents() {

    itemsScrollPane = new javax.swing.JScrollPane();
    itemsTable = new javax.swing.JTable();
    controlPanel = new javax.swing.JPanel();

    setLayout(new java.awt.BorderLayout());

    itemsTable.setModel(new javax.swing.table.DefaultTableModel(
      new Object [][] {

      },
      new String [] {

      }
    ));
    itemsScrollPane.setViewportView(itemsTable);

    add(itemsScrollPane, java.awt.BorderLayout.CENTER);

    controlPanel.setLayout(new java.awt.GridBagLayout());
    add(controlPanel, java.awt.BorderLayout.EAST);
  }// </editor-fold>//GEN-END:initComponents

  // CHECKSTYLE:OFF
  // Variables declaration - do not modify//GEN-BEGIN:variables
  private javax.swing.JPanel controlPanel;
  private javax.swing.JScrollPane itemsScrollPane;
  private javax.swing.JTable itemsTable;
  // End of variables declaration//GEN-END:variables
  // CHECKSTYLE:ON

  protected class ItemsTableModel
      extends AbstractTableModel {

    private final Class<?>[] COLUMN_CLASSES = new Class<?>[]{
      TCSResourceReference.class,
      TCSResourceReference.class,
      TCSResourceReference.class
    };

    /**
     * The column names.
     */
    private final String[] COLUMN_NAMES = new String[]{
      BUNDLE.getString("resourcePropertyViewerEditorPanel.table_resources.column_path.headerText"),
      BUNDLE.getString("resourcePropertyViewerEditorPanel.table_resources.column_point.headerText"),
      BUNDLE.getString("resourcePropertyViewerEditorPanel.table_resources.column_location.headerText")
    };

    private final int COLUMN_PATH = 0;
    private final int COLUMN_POINT = 1;
    private final int COLUMN_LOCATION = 2;

    private List<List<TCSResourceReference<?>>> values = new LinkedList<>();

    public ItemsTableModel() {
    }

    @Override
    public Class<?> getColumnClass(int columnIndex) {
      return COLUMN_CLASSES[columnIndex];
    }

    @Override
    public String getColumnName(int columnIndex) {
      return COLUMN_NAMES[columnIndex];
    }

    @Override
    public boolean isCellEditable(int row, int column) {
      return false;
    }

    @Override
    public int getRowCount() {
      return values.size();
    }

    @Override
    public int getColumnCount() {
      return COLUMN_NAMES.length;
    }

    @Override
    public Object getValueAt(int rowIndex, int columnIndex) {
      if (rowIndex < 0 || rowIndex >= getRowCount()) {
        return null;
      }
      List<TCSResourceReference<?>> entry = values.get(rowIndex);
      switch (columnIndex) {
        case COLUMN_PATH:
          return entry.get(COLUMN_PATH);
        case COLUMN_POINT:
          return entry.get(COLUMN_POINT);
        case COLUMN_LOCATION:
          return entry.get(COLUMN_LOCATION);
        default:
          throw new IllegalArgumentException("Invalid column index: " + columnIndex);
      }
    }

    public void setValues(List<List<TCSResourceReference<?>>> values) {
      this.values = values;
    }
  }

}
